<?php 
/**
 * This file is part of DomMvc.
 * 
 * DomMvc is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomMvc is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomMvc.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */

/**
* This library is not free software. You can not redistribute it and/or modify it in anyway!
* 
* @package DomMvc
*/
abstract class DomController {
	
	/**
	* @var String 
	*/
	private $name;
	
	/**
	* @param String $name Controller name.
	*/
	final public function __construct( $name ) {
		$this->name = $name;
	}

	final public function __get( $var ) {
		switch( $var ){
			case 'view':
				return $this->getView();
			case 'name':
				return $this->name;
			default:
				throw new RuntimeException('Can\'t access <strong>'.$var.'</strong>');
		}
	}
	
	/**
	* @return DomView Site main renderer.
	*/
	final public function getView() {
		return $this->getSite()->getView();
	}
	
	/**
	* @param String $add Add extra arguments to url.
	* @return String Current Controller url
	*/
	final public function getUrl( $add = NULL ) {
		return $this->getSite()->getUrl() . $this->name . '/' . $add;
	}
	
	/**
	* @param String $add Add extra arguments to url.
	* @return String Site url
	*/
	final public function getSiteUrl( $add = NULL ) {
		return $this->getSite()->getUrl() . $add;
	}	
	/**
	 * @param String $add Add extra arguments to url
	 * @return String Current url (All GET params)
	 */
	final public function getCurrentUrl( $add = NULL ) {
		return $this->getSite()->getCurrentUrl( $add );
	}
	/**
	* @return String
	*/
	public function getTemplateUrl( $add = NULL ) {
		return $this->getSite()->getTemplateUrl( $add );
	}
	
	/**
	* @return String
	*/
	public function getMediaUrl( $add = NULL ) {
		return $this->getSite()->getMediaUrl( $add );
	}
	/**
	* @return DomSite 
	*/
	final public function getSite() {
		return $GLOBALS['SITE'];
	}
	
	
	
	/**
	* Load custom controller.
	* @param String $name Controller name
	* @param String $group Controller group
	*/
	final public function loadController( $name, $group = NULL ) {
		return $this->getSite()->loadController( $name, $group );
	}
	
	/**
	* Index method. This will be called when nothing is selected.
	*/
	public function index() {}
	
	/**
	* Error method. This will be called when selected page doesn't exist.
	*/
	public function error404() {
		if( !headers_sent() ) header("HTTP/1.0 404 Not Found");
		//$this->view->setTemplate('Errors/error404.html');
	}
	
	/**
	* Forbidden error method.
	* @param Int $errorCode [1-no user, 2-user blocked, 3-not authorized]
	* @param String $errorMessage
	*/
	public function error403( $errorCode, $errorMessage ) {
		if( !headers_sent() ) header("HTTP/1.0 403 Forbidden"); 
		//$this->view->setTemplate('Errors/error403.html');
		//$this->view->errorCode = $errorCode;
		//$this->view->errorMessage = $errorMessage;
	}
	
	
	/**
	 * Goes to section. Same as self::goTo( self::getUrl('section-name') );
	 *
	 * @param unknown_type $add
	 */
	public function goToSection( $add = NULL ) {
		$this->goToUrl( $this->getUrl($add) );
	}
	
	/**
	 * Goes to url. If it is not started with http then site url is added as prefix.
	 * If url is not added then user is directed to site url.
	 * 
	 * PHP script is killed when this method is called!
	 *
	 * @param String $url
	 */
	public function goToUrl( $url = NULL ) {
		if( substr($url,0,4) != 'http' )
			$url = $this->getSite()->getUrl() . $url;
		
		if( headers_sent() )
			echo 'Go to <a href="'.$url.'">'.$this->getUrl($add).'</a>';
		else
			header('location:'.$url);
		die();
	}
	
	
	
	
	
	
	
	/**
	* @param String $resource
	* Checks if user has $resource allowed.
	* @return Boolean
	*/
	public function isAllowed( $resource = NULL ) {
		$user = $this->getUser();
		return (bool)( $user && ($resource === NULL or $user->rights->isAllowed( $resource ) ) && $user->blocked === false );
	}
	
	/**
	* @param String $resource
	* You can give multiple resources by using | or &. A&B means that both rights must be set, A|B means that A or B must be set. You can use both of them together.
	* If you want to test for value user A=my value&B=my second value
	* Checks if user has allowed to view controller method. If not then NotAuthorizedException exception is raised. 
	* If you give empty string it only checks that user is logged in and not blocked!
	* DomSite automatically cathes it and shows 403 error page.
	* Samples:
	* <code>
	* // allow admin
	* $this->auth('admin');
	* // allow admin or user
	* $this->auth('admin|user);
	* // allow only users who are admin and owners
	* $this->auth('admin&owner');
	* // allow only users who's admin value is 3
	* $this->auth('admin=3);
	* </code>
	* 
	* @return true
	*/
	public function auth( $resource = '' ) {
		
		$user = $this->getUser();
		if( !$user )
			throw new NotAuthorizedException( 'No user found', 1);
		elseif( $user->blocked === true )
			throw new NotAuthorizedException( $user->blockReason, 2 );
		
		if( $resource === '' )
			return;
		
		$overallAllowed = false;
		$resources = explode('|', $resource );
	
		foreach( $resources as $resource ) {
			$parts = explode('&',$resource);
			$allowed = true;
			
			foreach( $parts as $part ) {
				
				$part  = explode('=',$part);
				if( isset($part[1]) ) {
					$allowed = (bool)$this->getUser()->rights->getValue($part[0]) == $part[1];
				} else {
					$allowed = (bool)$this->getUser()->rights->isAllowed($part[0]);
				}
			}
			
			if( $allowed == true ) {
				$overallAllowed = true;
			}
			
		}
	
		if( $overallAllowed === false) {
			throw new NotAuthorizedException( 'Not authorized ('.$resource.')', 3 );
		}
		
		return true;
	}
	
	/**
	* @return DomUser Current site user.
	*/
	public function getUser() {
		return $GLOBALS['SITE']->user;
	}
	
	/**
	* This method will be called before controller controlling methods.
	* Good for making stuff for every page or authorization checks etc.
	* If this method returns "false" Index controller setup method will be called.
	*/
	public function setup() {
		return false;
	}
	
	/**
	* This method will be called after controller controlling methods.
	* Good for making stuff after main controllers.
	* If this method returns "false" Index controller setup method will be called.
	*/
	public function finalize() {
		return false;
	}

}
?>